package com.tang.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tang.constants.SystemConstants;
import com.tang.dto.MenuListDto;
import com.tang.enums.AppHttpCodeEnum;
import com.tang.sys.ResponseResult;
import com.tang.sys.entity.Menu;
import com.tang.sys.entity.Role;
import com.tang.sys.entity.RoleMenu;
import com.tang.sys.mapper.MenuMapper;
import com.tang.sys.mapper.RoleMapper;
import com.tang.sys.mapper.RoleMenuMapper;
import com.tang.sys.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tang.sys.service.IRoleMenuService;
import com.tang.sys.vo.AdminRoleUpdateMenuVo;
import com.tang.sys.vo.CategoryVo;
import com.tang.sys.vo.MenuRoleVo;
import com.tang.sys.vo.MenuVo;
import com.tang.utils.BeanCopyUtils;
import com.tang.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author shankaka
 * @since 2023-04-19
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Resource
    private MenuMapper menuMapper;

    @Autowired
    private IMenuService iMenuService;
    @Autowired
    private IRoleMenuService iRoleMenuService;

    @Resource
    private RoleMenuMapper roleMenuMapper;
    @Resource
    private RoleMapper roleMapper;

    @Override
    public List<String> selectPermsByUserId(Long id) {
        //如果是管理员返回所有的权限
        if (SecurityUtils.isAdmin()){
            LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Menu::getMenuType,SystemConstants.MENU,SystemConstants.BUTTON);
            wrapper.eq(Menu::getStatus,SystemConstants.LINK_STATUS);
            List<Menu> menus = list(wrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        //否则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if(SecurityUtils.isAdmin()){
            //如果是 获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        }else{
            //否则  获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<Menu> menuTree = builderMenuTree(menus,0L);
        return menuTree;
    }

    @Override
    public List<MenuVo> AllListMenu() {
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Menu::getComponent);
        List<Menu> menuList = baseMapper.selectList(wrapper);
        List<MenuVo> list = BeanCopyUtils.copyBeanList(menuList, MenuVo.class);
        return list;
    }

    @Override
    public ResponseResult<MenuVo> addMenuList(MenuVo menuVo) {
        Menu menu = new Menu();
        BeanUtils.copyProperties(menuVo, menu);
        menuMapper.insert(menu);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getMenuList(String id) {
        Menu byId = iMenuService.getById(id);
        if (byId != null) {
            MenuVo menuVo = new MenuVo();
            BeanUtils.copyProperties(byId, menuVo);
            return ResponseResult.okResult(menuVo);
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.valueOf("分类不存在"));
        }

    }

    @Override
    public ResponseResult<MenuVo> updateMenu(MenuVo menuVo) {
        Menu menu = menuMapper.selectById(menuVo.getId());
        if (menu == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.valueOf("未找到"));
        }
        BeanUtils.copyProperties(menuVo,menu);
        menuMapper.updateById(menu);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteMenu(Long id) {
        this.menuMapper.deleteById(id);

        return ResponseResult.okResult();
    }

    //添加角色查询菜单显示
    @Override
    public ResponseResult getRoleMenuList() {
        //查询对应的根目录
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getParentId,SystemConstants.MENU_MULU);
        List<Menu> menuList = menuMapper.selectList(wrapper);
        List<MenuRoleVo> menuRoleVoList = new ArrayList<>();
        for (Menu menu : menuList) {
            MenuRoleVo menuRoleVo = convertMenuToMenuVo(menu);
            builderMenuTree(menuRoleVo);
            menuRoleVoList.add(menuRoleVo);
        }
        return ResponseResult.okResult(menuRoleVoList);
    }

    //修改方法的菜单
    @Override
    public ResponseResult getRoleMenuUpdate(Long id) {
        //获取角色的id
        Role role = this.roleMapper.selectById(id);
        List<Long> menuIdListByRoleId = roleMenuMapper.getMenuIdListByRoleId(id);
        role.setMenuIds(menuIdListByRoleId);

        //获取全部的菜单menu  根目录
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getParentId,SystemConstants.MENU_MULU);
        List<Menu> menuList = menuMapper.selectList(wrapper);
        List<MenuRoleVo> menuRoleVoList = new ArrayList<>();
        //定义一个checkdkeys把role的菜单存入进去
        List<Long> checkedKeys = new ArrayList<>(role.getMenuIds());
        for (Menu menu : menuList) {
            MenuRoleVo menuRoleVo = convertMenuToMenuVo(menu);

            builderMenuTree(menuRoleVo);
            menuRoleVoList.add(menuRoleVo);
        }
        //查询到角色id所拥有的菜单权限


        return ResponseResult.okResult(new AdminRoleUpdateMenuVo(menuRoleVoList, checkedKeys));
    }








    private MenuRoleVo convertMenuToMenuVo(Menu menu) {
        MenuRoleVo menuRoleVo = new MenuRoleVo();
        menuRoleVo.setId(menu.getId());
        menuRoleVo.setLabel(menu.getMenuName());
        BeanUtils.copyProperties(menu, menuRoleVo);
        return menuRoleVo;
    }


    private void builderMenuTree(MenuRoleVo menuRoleVo) {
        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getParentId,menuRoleVo.getId());
        List<Menu> menuList = menuMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(menuList)){
            return;
        }
        List<MenuRoleVo> children = new ArrayList<>();
        for (Menu menu : menuList) {
            MenuRoleVo childMenu = convertMenuToMenuVo(menu);
            builderMenuTree(childMenu);
            children.add(childMenu);
        }
        menuRoleVo.setChildren(children);
    }


    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }


    /**
     * 获取存入参数的 子Menu集合
     * @param menu
     * @param menus
     * @return
     */

    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m->m.setChildren(getChildren(m,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }

}
